<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { useUserStore } from '@/stores'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { type IDomEditor, type IEditorConfig, type IToolbarConfig } from '@wangeditor/editor'
import { Boot } from '@wangeditor/editor'
import markdownModule from '@wangeditor/plugin-md'
import { Add } from '@vicons/ionicons5'
import type { UploadFileInfo, FormRules } from 'naive-ui'
import { topicGetTopicDetailService, topicAddTopicService, topicUpdateTopicService } from '@/api/topic'
import { imageUrlToFile } from '@/hooks/imageUrlToFile'

const message = useMessage()
Boot.registerModule(markdownModule)

// Then create editor and toolbar

//是否显示抽屉
const show: Ref<boolean> = ref(false)
const userStore = useUserStore()

//表单数据类型
type FormModel = {
  id: number | null
  t_uid: number
  t_kind: string
  t_title: string
  t_content: string
  t_photo: File | null
  t_introduce: string
  [key: string]: any
}
//预览图片
const imgUrl: Ref<string> = ref('')
//默认表单数据
const defaultFormModel: FormModel = {
  id: null,
  t_uid: userStore.userInfo.id,
  t_kind: '',
  t_title: '',
  t_content: '',
  t_photo: null,
  t_introduce: ''
}
//表单数据
const formModel: Ref<FormModel> = ref({
  ...defaultFormModel
})
//校验规则
const rules: FormRules = {
  t_title: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  t_kind: [{ required: true, message: '请输入分类', trigger: 'blur' }],
  t_introduce: [{ required: true, message: '请输入简介', trigger: 'blur' }],
  t_content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
}
//图片上传
// 上传前的钩子函数限制只能上传一张图片
const fileList: Ref<Array<File>> = ref([])
const beforeUpload = (file: File) => {
  fileList.value = [] // 清空 fileList
  fileList.value.push(file)
  return true
}
// 上传图片预览
const handleImgChange = (fileList: UploadFileInfo[]) => {
  console.log(fileList)
  const file = fileList[0].file as File
  //更新表单数据,表单数据并没有upload绑定，所以这里需要手动更新
  formModel.value.t_photo = file
  imgUrl.value = URL.createObjectURL(file)
}

//编辑器实例
const editorRef = shallowRef()

//编辑器配置
const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: ['uploadImage', 'uploadVideo', 'insertVideo', 'insertVideo', 'insertImage', 'deleteImage', 'editImage']
}
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  MENU_CONF: {}
}
//检查 MENU_CONF 是否已经定义，如果没有定义，初始化为一个空对象
editorConfig.MENU_CONF = editorConfig.MENU_CONF || {}
editorConfig.MENU_CONF['codeSelectLang'] = {
  // 代码语言
  codeLangs: [
    { text: 'CSS', value: 'css' },

    { text: 'HTML', value: 'html' },

    { text: 'XML', value: 'xml' },

    { text: 'Javascript', value: 'javascript' },
    { text: 'Typescript', value: 'typescript' },

    { text: 'JSX', value: 'jsx' },

    { text: 'Go', value: 'go' },

    { text: 'PHP', value: 'php' },

    { text: 'C', value: 'c' },

    { text: 'Python', value: 'python' },

    { text: 'Java', value: 'java' },

    { text: 'C++', value: 'cpp' },

    { text: 'C#', value: 'csharp' },

    { text: 'Visual Basic', value: 'visual-basic' },

    { text: 'SQL', value: 'sql' },

    { text: 'Ruby', value: 'ruby' },

    { text: 'Swift', value: 'swift' },

    { text: 'Bash', value: 'bash' },

    { text: 'Lua', value: 'lua' },

    { text: 'Groovy', value: 'groovy' },

    { text: 'Markdown', value: 'markdown' }
    // 其他
  ]
}

const mode: Ref<'default' | 'simple'> = ref('default')
//创建编辑器实例
const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor
  console.log(editor.getMenuConfig('codeSelectLang').codeLangs)
}
//编辑器内容改变
const handleContentChange = () => {}
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
const formRef = ref()
const onSubmit = async () => {
  if (isEdit.value) {
    await formRef.value.validate()
    //编辑
    const formData = new FormData()
    for (let key in formModel.value) {
      formData.append(key, formModel.value[key])
    }
    await topicUpdateTopicService(formData)
    console.log(...formData.entries())
    message.success('编辑成功')
    //通知更新页面
    emit('updateData', 'edit')
  } else {
    await formRef.value.validate()
    //新增
    const formData = new FormData()
    for (let key in formModel.value) {
      // id不需要传递
      if (key === 'id') continue
      formData.append(key, formModel.value[key])
    }
    await topicAddTopicService(formData)
    console.log(...formData.entries())
    message.success('新增成功')
    //通知更新页面
    emit('updateData', 'add')
  }
  show.value = false
  //刷新列表
  // onSearch()
}

//是否编辑
const isEdit: Ref<boolean> = ref(false)
//更新页面
const emit = defineEmits<{ updateData: [operate: string] }>()
//打开抽屉
const open = async (id?: number) => {
  show.value = true
  if (id) {
    //编辑
    const res = await topicGetTopicDetailService(id)
    const t_photo = await imageUrlToFile(res.data.data.t_photo, 'cover.jpg')
    formModel.value = {
      id: res.data.data.id,
      t_uid: res.data.data.t_uid,
      t_kind: res.data.data.t_kind,
      t_title: res.data.data.t_title,
      t_content: res.data.data.t_content,
      t_photo: t_photo,
      t_introduce: res.data.data.t_introduce
    }
    imgUrl.value = URL.createObjectURL(t_photo)
    isEdit.value = true
  } else {
    //新增
    isEdit.value = false
    formModel.value = {
      ...defaultFormModel
    }
    imgUrl.value = ''
  }
}
defineExpose({
  open
})
</script>

<template>
  <n-drawer v-model:show="show" :width="850">
    <n-drawer-content :native-scrollbar="false" :title="isEdit ? '编辑文章' : '新增文章'" closable>
      <n-form :model="formModel" :rules="rules" ref="formRef">
        <n-form-item label="文章标题" path="t_title">
          <n-input v-model:value="formModel.t_title" placeholder="请输入标题" />
        </n-form-item>
        <n-form-item label="文章分类" path="t_kind">
          <n-input v-model:value="formModel.t_kind" placeholder="请输入文章分类"> </n-input>
        </n-form-item>
        <n-form-item label="文章简介" path="t_introduce">
          <n-input v-model:value="formModel.t_introduce" placeholder="请输入简介" />
        </n-form-item>
        <n-form-item label="文章封面">
          <n-upload
            list-type="image-card"
            :default-upload="false"
            :file-list="fileList"
            :before-upload="beforeUpload"
            :show-preview-button="false"
            :multiple="false"
            :on-update:file-list="handleImgChange"
            class="relative rounded-2"
          >
            <img v-if="imgUrl" :src="imgUrl" class="w-full h-full rounded" alt="哈哈" />
            <n-icon v-show="!imgUrl" :component="Add" class="absolute"></n-icon>
          </n-upload>
        </n-form-item>
        <n-form-item label="文章内容" path="t_content">
          <div style="border: 1px solid #ccc">
            <Toolbar
              style="border-bottom: 1px solid #ccc"
              :editor="editorRef"
              :defaultConfig="toolbarConfig"
              :mode="mode"
            />
            <Editor
              style="height: 500px; overflow-y: hidden"
              v-model="formModel.t_content"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="handleCreated"
              @change="handleContentChange"
            />
          </div>
        </n-form-item>

        <n-form-item>
          <n-button type="primary" :on-click="() => onSubmit()" secondary>提交</n-button>
        </n-form-item>
      </n-form>
    </n-drawer-content>
  </n-drawer>
</template>

<style scoped></style>
